#include "messageshowarea.h"
#include <QLabel>
#include <QPushButton>
#include <QScrollBar>
#include <QVBoxLayout>
#include <QFontMetrics>
#include <QPainter>
#include <QPainterPath>

#include "debug.h"
using namespace model;
///////////////////////////////////////
/// 表示消息展示区
///////////////////////////////
MessageShowArea::MessageShowArea() {
    //1.初始化基本属性
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);


    //设置这个属性才能开始滚动
    this->setWidgetResizable(true);
    //滚动条相关样式
    this->verticalScrollBar()->setStyleSheet("QScrollBar:vertical{width:4px;background-color:rgb(255, 255, 255);}");
    this->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal {height:0px;}");
    //设置item没有边框
    this->setStyleSheet("ScrollArea {border:none;}");
    //2. 创建一个container，包含内部元素的容器
    container = new QWidget();
    this->setWidget(container);


    //给container添加布局管理器
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setSpacing(0);
    layout->setContentsMargins(0, 0, 0, 0);
    container->setLayout(layout);


    //构造测试数据
#if TEST_UI
    for(int i = 0;i<30;i++){
        UserInfo userInfo;
        userInfo.nicnname = "张三"+QString::number(i);
        userInfo.avatar = QIcon(":/resource/image/defaultAvatar.jpg");
        Message message = Message::makeMessage(model::TEXT_TYPE, "", userInfo, ("这是一条消息"+QString::number(i)).toUtf8(), "");
        this->addMessage(true, message);
    }
    UserInfo userInfo;
    userInfo.nicnname = "张三";
    userInfo.avatar = QIcon(":/resource/image/defaultAvatar.jpg");
    Message message = Message::makeMessage(model::TEXT_TYPE, "", userInfo, QString("这是一条消息这是一条消息这是一条消息这是一条消息这是一条消息这是一条消息这是一条消息").toUtf8(), "");
    this->addMessage(true, message);
    Message message1 = Message::makeMessage(model::TEXT_TYPE, "", userInfo, QString("这息这是一条消息这是一条消息这是一条消息这是一条消息这是一条消息这是一条消息这是一条消息这是一条消息这是一条消息这是一条消息这是一条消息").toUtf8(), "");
    this->addMessage(false, message1);
#endif
}

void MessageShowArea::addMessage(bool isLeft, const Message &message)
{
    //构造MessageItem添加到布局管理去中
    MessageItem* messageItem = MessageItem::makeMessageItem(isLeft, message);
    this->container->layout()->addWidget(messageItem);
    return;
}

//头插入
void MessageShowArea::addFontMessage(bool isLeft, const Message &message)
{
    //构造MessageItem添加到布局管理去中
    MessageItem* messageItem = MessageItem::makeMessageItem(isLeft, message);
    QVBoxLayout* layout = dynamic_cast<QVBoxLayout*>(this->container->layout());

    layout->insertWidget(0, messageItem);
    return;
}

void MessageShowArea::clear()
{
    QLayout* layout = this->container->layout();
    for(int i = layout->count()-1;i>=0;--i){
        QLayoutItem* item = layout->takeAt(i);
        if(item!=nullptr && item->widget()!=nullptr){
            delete item->widget();
        }
    }
}


///////////////////////////////////////
/// 表示一个消息元素
/// 这个里面要同时支持文本、图片、文件、语音消息
/// 当前只考虑文本消息，另外几个慢慢添加
///////////////////////////////
MessageItem::MessageItem(bool isLeft):isLeft(isLeft)
{

}

MessageItem *MessageItem::makeMessageItem(bool isLeft, const Message &message)
{
    //构造出一条消息所涉及的部分
    MessageItem* messageItem = new MessageItem(isLeft);
    QGridLayout* layout= new QGridLayout();

    layout->setSpacing(10);
    layout->setContentsMargins(20, 10, 40, 0);
    messageItem->setMinimumHeight(100);  //最低不能低于100
    messageItem->setLayout(layout);

    //2. 创建头像
    QPushButton* avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(40, 40);
    avatarBtn->setIconSize(QSize(40, 40));
    avatarBtn->setIcon(message.sender.avatar);

    //总共分成两列
    if(isLeft){
        layout->addWidget(avatarBtn, 0, 0, 2, 1, Qt::AlignTop| Qt::AlignLeft);  //占据两行1列
    }
    else{
        layout->addWidget(avatarBtn, 0, 1, 2, 1, Qt::AlignTop| Qt::AlignRight);  //占据两行1列
    }

    // 3. 创建名字和时间
    QLabel* nameLabel = new QLabel();
    nameLabel->setText(message.sender.nicnname+" | " + message.time);
    nameLabel->setAlignment(Qt::AlignBottom);
    nameLabel->setStyleSheet("QLabel {font-size:12px;color:rgb(178, 178, 178);}");
    if(isLeft){
        layout->addWidget(nameLabel, 0, 1);  //默认不写就是占据1行1列
    }else{
        layout->addWidget(nameLabel, 0, 0, Qt::AlignRight);  //默认不写就是占据1行1列
    }

    //4.创建消息体
    QWidget* contentWidget = nullptr;
    switch (message.messageType){
    case TEXT_TYPE:
        contentWidget = makeTextMessageItem(isLeft, message.content);
        break;
    case IMAGE_TYPE:
        contentWidget = makeImageMessageItem();
        break;
    case FILE_TYPE:
        contentWidget = makeFileMessageItem();
        break;
    case SPEECH_TYPE:
        contentWidget = makeSpeechMessageItem();
        break;
    default:
        LOG()<<"错误的消息类型 ！ messageType="<<message.messageType;
    }
    if(isLeft){
        layout->addWidget(contentWidget, 1, 1);
    }else{
        layout->addWidget(contentWidget, 1, 0);
    }
    return messageItem;
}

QWidget *MessageItem::makeTextMessageItem(bool isLeft, const QString& text)
{
    MessageContentLabel* messageContentLabel = new MessageContentLabel(text, isLeft);
    return messageContentLabel;
}

QWidget *MessageItem::makeImageMessageItem()
{
    return nullptr;
}

QWidget *MessageItem::makeFileMessageItem()
{
    return nullptr;
}

QWidget *MessageItem::makeSpeechMessageItem()
{
    return nullptr;
}

///////////////////////////////
/// 表示"文本消息" 正文部分
///////////////////////////////
MessageContentLabel::MessageContentLabel(const QString &text, bool isLeft):isLeft(isLeft)
{
    //设置一下尺寸策略
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    QFont font;
    font.setFamily("微软雅黑");
    font.setPixelSize(16);
    this->label = new QLabel(this);
    this->label->setText(text);
    this->label->setFont(font);
    this->label->setAlignment(Qt::AlignVCenter|Qt::AlignLeft);
    this->label->setWordWrap(true);  //自动换行
    this->label->setStyleSheet("QLabel {padding: 0 10px;line-height:1.2; color:black; background-color:transparent;}");

    // 最难确保尺寸和文字是适配的

}

//这个函数会在该控件被显示的时机自动调用到
void MessageContentLabel::paintEvent(QPaintEvent *event)
{
    //1. 获取到父元素的宽度
    QObject* object = this->parent();
    if(!object->isWidgetType()){
        //当前这个对象父元素不是预期的QWidget，直接忽略
        return;
    }
    QWidget* parent = dynamic_cast<QWidget*>(object);
    int width = parent->width()*0.6;    //文字只占据父控件的60%

    //2. 计算当前文本的宽度
    QFontMetrics metrics(this->label->font());
    int totalWidth = metrics.horizontalAdvance(this->label->text());  //计算单行的宽度

    //3. 计算出此处的行数是多少
    int rows = (totalWidth/(width-40))+1;      //+1是为了至少有1行
    if(rows==1){
        //只有一行
        width = totalWidth+40;
    }

    //4. 根据行数，计算得到的高度
    int height = rows*(this->label->font().pixelSize()*1.2)+20;   //20是上下边距

    //5. 绘制矩形和圆角箭头
    QPainter painter(this);
    QPainterPath path;
    //设置抗锯齿
    painter.setRenderHint(QPainter::Antialiasing);
    if(isLeft){
       //创建画笔和刷子
        painter.setPen(QPen(QColor(255, 255, 255)));
        painter.setBrush(QColor(255, 255, 255));
        //绘制圆角矩形
        painter.drawRoundedRect(10, 0, width, height, 10, 10);
        //绘制三角形
        path.moveTo(10, 15);
        path.lineTo(0, 20);
        path.lineTo(10, 25);
        path.closeSubpath(); //绘制的线行成闭合的多边形，才能使用BRush填充颜色
        painter.drawPath(path);  //不要忘记真正的绘图操作

        this->label->setGeometry(10, 0, width, height);   //将文字放到图形里
    }else{
        //创建画笔和刷子
        painter.setPen(QPen(QColor(0, 255, 0)));
        painter.setBrush(QColor(0, 255, 0));

        //绘制圆角矩形
        int leftPos = this->width()-10-width;
        int rightPos = this->width()-10;
        painter.drawRoundedRect(leftPos, 0, width, height, 10, 10);
        //绘制三角形
        path.moveTo(rightPos, 15);
        path.lineTo(rightPos+10, 20);
        path.lineTo(rightPos, 25);
        path.closeSubpath(); //绘制的线行成闭合的多边形，才能使用BRush填充颜色
        painter.drawPath(path);  //不要忘记真正的绘图操作

        this->label->setGeometry(leftPos, 0, width, height);   //将文字放到图形里
    }

    //6. 确保父元素的高度是足够的
    // 确保高度要涵盖名字 label  文字  再留点余量
    parent->setFixedHeight(height+50);
}
